local destiny = fk.CreateSkill {
  name = "#lvshi__destiny&",
  mode_skill = true,
}

local U = require "packages/utility/utility"

local function is_arithmetic_sequence(t)
  -- 检查元素数量是否至少为3
  if #t < 3 then
      return false
  end 
  -- 创建数组副本并排序（避免修改原数组）
  local sorted = {}
  for i, v in ipairs(t) do
      sorted[i] = v
  end
  table.sort(sorted)
  -- 计算公差（必须大于0）
  local d = sorted[2] - sorted[1]
  if d <= 0 then
      return false
  end
  -- 验证后续元素是否满足等差数列
  for i = 3, #sorted do
      if sorted[i] - sorted[i-1] ~= d then
          return false
      end
  end
  return true
end

local checkUniqueRoles = function(room)
  local identity_count = { lord = 0, loyalist = 0, rebel = 0, renegade = 0, civilian = 0 }--身份出现次数
  for _, p in ipairs(room.alive_players) do
      local role = p.role
      if role == "rebel_chief" then role = "rebel" end
      if identity_count[role] then
          identity_count[role] = identity_count[role] + 1
      else
          -- 处理未知身份（如扩展包角色）
          return false
      end
  end
  -- 校验主公唯一性
  if identity_count.lord ~= 1 then return false end
  -- 校验其他身份不重复
  for role, count in pairs(identity_count) do
      if role ~= "lord" and count > 1 then
          return false
      end
  end
  return true
end

destiny:addEffect(fk.TurnEnd, {
  mute = true,
  priority = 0.01,
  can_trigger = function(self, event, target, player, data)
    local room = player.room
    if #U.getPrivateMark(player, "destiny") == 0 or player.role ~= "renegade" then return end
    if U.getPrivateMark(player, "destiny")[1] == "lvshi__zhengmiao" then--拯庙
      return #table.filter(room:getAlivePlayers(), function (p)
        return p.role == "loyalist" end) == 0 and
        #table.filter(room:getAlivePlayers(), function (p)
          return p.role == "rebel" or p.role == "rebel_chief" end) > 0
    elseif U.getPrivateMark(player, "destiny")[1] == "lvshi__qingce" then--清侧
      local roles = {}
      for _, p in ipairs(room:getAlivePlayers()) do
        local role = p.role
        if role == "rebel_chief" then role = "rebel" end
        table.insertIfNeed(roles, role)
      end
      return #roles == room:getBanner("RoundCount")
    elseif U.getPrivateMark(player, "destiny")[1] == "lvshi__zhengshi" then--争师
      return table.find(room.players, function (p) return p.role == "rebel_chief" and p.dead end)
    elseif U.getPrivateMark(player, "destiny")[1] == "lvshi__shenye" then--申野
      return is_arithmetic_sequence(table.map(room:getAlivePlayers(), function (p) return p:getHandcardNum() end))
    elseif U.getPrivateMark(player, "destiny")[1] == "lvshi__xuanyin" then--玄隐
      local max_hp = 0
      for _, p in ipairs(room:getAlivePlayers()) do
        if p.role ~= "lord" then
          max_hp = math.max(max_hp, p.hp)
        end
      end
      return max_hp <= 2
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerProperty(player, "role_shown", true)
    --room:notifySkillInvoked(player, "destiny", "big")
    room:sendLog{type = "#destinycomplete", from = player.id, arg = U.getPrivateMark(player, "destiny")[1], toast = true}
    if U.getPrivateMark(player, "destiny")[1] == "lvshi__zhengmiao" then
      room:setPlayerProperty(player, "role", "loyalist")
    elseif U.getPrivateMark(player, "destiny")[1] == "lvshi__shenye" then
      room:gameOver("renegade")
    elseif U.getPrivateMark(player, "destiny")[1] == "lvshi__qingce" then
      room:setPlayerProperty(player, "role", "rebel")
      player:drawCards(2, "lvshi__qingce")
    elseif U.getPrivateMark(player, "destiny")[1] == "lvshi__zhengshi" then
      room:setPlayerProperty(player, "role", "rebel_chief")
    elseif U.getPrivateMark(player, "destiny")[1] == "lvshi__xuanyin" then
      room:changeMaxHp(player, -1)
      room:setPlayerProperty(player, "role", "civilian")
    end
    room:setPlayerMark(player, "@[:]destiny", U.getPrivateMark(player, "destiny")[1])
    room:setPlayerMark(player, "@[private]destiny", 0)
    local rebels = table.filter(room.alive_players, function (p)
      return p.role == "renegade" or p.role == "rebel" or p.role == "rebel_chief" end)
    if #rebels == 0 then
      room:gameOver("lord+loyalist")
    end
  end,
})

destiny:addEffect(fk.BeforeGameOverJudge, {
  mute = true,
  priority = 0.01,
  can_trigger = function(self, event, target, player, data)
    if #U.getPrivateMark(player, "destiny") == 0 or player.role ~= "renegade" or player.dead then return end
    if U.getPrivateMark(player, "destiny")[1] == "lvshi__duotian" then
      return player:getMark("evil-count") >= 1 and data.killer and data.killer == player
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerProperty(player, "role_shown", true)
    room:notifySkillInvoked(player, "destiny", "big")
    room:sendLog{type = "#destinycomplete", from = player.id, arg = U.getPrivateMark(player, "destiny")[1], toast = true}
    local lord = table.find(room.players, function(p) return p.role == "lord" end)
    if lord then
      room:setPlayerProperty(lord, "role", "renegade")
      room:setPlayerProperty(player, "role", "lord")
      if player:isWounded() then
        room:recover{ who = player, num = player:getLostHp(), skillName = "lvshi__duotian" }
      end
      local lvshi__policy = room:getBanner("@[:]lvshi__policy")
      if lvshi__policy then
        room:handleAddLoseSkills(lord, "-"..lvshi__policy, nil, false)
        room:handleAddLoseSkills(player, lvshi__policy, nil, false)
      end
    end
  end,
})

destiny:addEffect(fk.Death, {
  can_refresh = function (self, event, target, player, data)
    return data.killer and data.killer == player and U.getPrivateMark(player, "destiny")[1] == "lvshi__duotian"
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:addPlayerMark(player, "evil-count")
  end
})

destiny:addEffect(fk.EventPhaseStart, {
  mute = true,
  is_delay_effect = true,
  can_trigger = function(self, event, target, player, data)
    if #U.getPrivateMark(player, "destiny") == 0 or player.role ~= "renegade" then return end
    if target == player and player.phase == Player.Start then
      if U.getPrivateMark(player, "destiny")[1] == "lvshi__jianbing" then
        return checkUniqueRoles(player.room)
      elseif U.getPrivateMark(player, "destiny")[1] == "lvshi__kuntu" then
        return player:isWounded() and player:usedSkillTimes(destiny.name, Player.HistoryGame) == 0
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerProperty(player, "role_shown", true)
    room:notifySkillInvoked(player, "destiny", "big")
    room:sendLog{type = "#destinycomplete", from = player.id, arg = U.getPrivateMark(player, "destiny")[1], toast = true}
    if U.getPrivateMark(player, "destiny")[1] == "lvshi__jianbing" then
      for _, p in ipairs(room:getOtherPlayers(player)) do
        if p.role == "rebel" or p.role == "rebel_chief" then
        else
          room:setPlayerProperty(p, "role", "rebel")
        end
      end
      room:setPlayerProperty(player, "role", "lord")
      --[[local n = #room:getOtherPlayers(player)
      room:changeMaxHp(player, n)
      room:recover{ who = player, num = n, skillName = "lvshi__jianbing" }]]
      --room:handleAddLoseSkills(player, "lvshi__gulve&|lvshi__zunwei&|lvshi__chongwu&", nil, false)
      local choices = {"lvshi__gulve&", "lvshi__zunwei&", "lvshi__chongwu&"}
      local policy = room:getBanner("@[:]lvshi__policy")
      if policy then
        table.removeOne(choices, policy)
      end
      local choice = room:askToChoice(player, {
        choices = choices,
        skill_name = "lvshi__jianbing",
      })
      room:handleAddLoseSkills(player, choice, nil, false)
      room:addPlayerMark(player, "jianbing_completed")
      --player:gainAnExtraTurn(true, "lvshi__jianbing")
    elseif U.getPrivateMark(player, "destiny")[1] == "lvshi__kuntu" then
      room:changeMaxHp(player, 1)
      local n = player.maxHp - player.hp
      room:recover{ who = player, num = n, skillName = "lvshi__kuntu" }
      player:drawCards(n, "lvshi__kuntu")
      room:handleAddLoseSkills(player, "lvshi__gulve&|lvshi__zunwei&|lvshi__chongwu&", nil, false)
    end
  end,
})

destiny:addEffect(fk.DrawNCards, {
  anim_type = "drawcard",
  is_delay_effect = true,
  mute = true,
  can_trigger = function(self, event, target, player, data)
    return target == player and U.getPrivateMark(player, "destiny")[1] == "lvshi__jianbing"
    and player:getMark("jianbing_completed") > 0
  end,
  on_use = function(self, event, target, player, data)
    data.n = #player.room:getAlivePlayers()
  end,
})

destiny:addEffect("maxcards", {
  correct_func = function(self, player)
    if U.getPrivateMark(player, "destiny")[1] == "lvshi__jianbing" and player:getMark("jianbing_completed") > 0 then
      return #Fk:currentRoom().alive_players
    end
  end,
})

Fk:loadTranslationTable{
  ["destiny"] = "天命",
  ["@[private]destiny"] = "天命",
  ["#destiny-get"] = "请选择你的天命",
  ["lvshi__qingce"] = "清侧",
  [":lvshi__qingce"] = "一名角色的回合结束后，若场上身份数等于轮次数，你将身份变为反贼，摸两张牌。",
  ["lvshi__duotian"] = "夺天",
  [":lvshi__duotian"] = "其他角色死亡时，若你杀死过两名角色，你与主公交换身份牌并回复所有体力，获得其“国策”。",
  ["lvshi__zhengmiao"] = "拯庙",
  [":lvshi__zhengmiao"] = "一名角色的回合结束后，若忠臣均已死亡且有反贼存活，你将身份变为忠臣。",
  ["lvshi__shenye"] = "申野",
  [":lvshi__shenye"] = "一名角色的回合结束后，若场上角色的手牌形成公差大于0的等差数列，你获胜。",

  ["lvshi__jianbing"] = "僭炳",
  [":lvshi__jianbing"] = "准备阶段，若场上身份数等于角色数，你将身份变为主公并获得一项主公没有的国策，然后其他角色身份变为反贼，你摸牌阶段改为摸X张牌，手牌上限+X（X为场上角色数）。",

  ["lvshi__kuntu"] = "困图",
  [":lvshi__kuntu"] = "觉醒技，准备阶段，若你已受伤，你增加1点体力上限，回复体力至上限，摸等量的牌，获得所有国策。",

  ["lvshi__xuanyin"] = "玄隐",
  [":lvshi__xuanyin"] = "一名角色的回合结束后，若非主公角色的体力值均不大于2，你减1点体力上限，然后你变为平民。",

  ["lvshi__zhengshi"] = "争师",
  [":lvshi__zhengshi"] = "一名角色的回合结束后，若贼首已死亡，你成为贼首（不获得先驱标记）。",

  ["@[:]destiny"] = "完成天命",
  ["#destinycomplete"] = "%from 已完成天命 %arg",
}

return destiny